package runnerworm.core;

import java.awt.*;

/**
 * <p>Title: Worm</p>
 * <p>Description: The world famous worm. The main character in our game. That
 * slimy thing that is running through a tunnel without purpose.</p>
 * @author Guilherme Mauro Germoglio Barbosa
 */

public class Worm {

  /**
   * Its head.
   */
  private WormParticle head;
  /**
   * Its body.
   */
  private WormParticle[] body;
  /**
   * The boolean that indicates if the worm is going up - Remember, if isn't
   * going up, it's going down.
   */
  private boolean goingUp;
  /**
   * The number of worm particle the body contains.
   */
  private final int NUMBER_OF_PARTICLES = 7;
  /**
   * The boolean that indicates if the worm is alive, or not.
   */
  private boolean isAlive;


  /**
   * Constructor. Creates its head and body. And indicates the worm is going down.
   * @param x The head's initial x coordinate.
   * @param y The head's initial y coordinate.
   */
  public Worm(double x, double y) {
    head = new WormParticle(x, y);
    body = new WormParticle[NUMBER_OF_PARTICLES];
    createBody(x, y);
    goingUp = false;
    isAlive = true;
  }

  /**
   * Will create all the body.
   * @param x The head's x coordinate.
   * @param y The head's y coordinate.
   */
  private void createBody(double x, double y) {
    for (int k = 0; k < NUMBER_OF_PARTICLES; k++) {
      x = x - 3;
      body[k] = new WormParticle(x, y);
    }
  }

  /**
   * Sets the head's coordinate. And transmits the changing to all body.
   * @param x The new x coordinate.
   * @param y The new y coordinate.
   */
  public void moveHead(double x, double y) {
    moveBody(head.get_X(), head.get_Y());
    head.set_X(x);
    head.set_Y(y);
  }

  /**
   * Will move the body according the head's coordinates.
   * @param x The head's x coordinate.
   * @param y The head's y coordinate.
   */
  private void moveBody(double x, double y) {
    for (int k = NUMBER_OF_PARTICLES-1; k > 0; k--) {
      body[k].set_Y(body[k-1].get_Y());
    }
    body[0].set_Y(y);
  }

  /**
   * Sets if the worm is going up or down.
   * @param isGoingUp True if it is going up, false case not.
   */
  public void setGoingUp(boolean isGoingUp) {
    this.goingUp = isGoingUp;
  }

  /**
   * Returns if the worm is going up or not.
   * @return True if it is going up, false case not.
   */
  public boolean isGoingUp() {
    return goingUp;
  }

  /**
   * Draws the worm.
   * @param g Where is to be drawn.
   */
  public synchronized void draw(Graphics g) {
    g.setColor(ColorTable.WORM_COLOR);
    head.draw(g);
    for (int k = 0; k < NUMBER_OF_PARTICLES; k++) {
      body[k].draw(g);
    }
  }

  /**
   * Erases the worm.
   * @param g Where is to be erased.
   */
  public synchronized void erase(Graphics g) {
    g.setColor(ColorTable.BACKGROUND_COLOR);
    head.draw(g);
    for (int k = 0; k < NUMBER_OF_PARTICLES; k++) {
      body[k].draw(g);
    }
  }


  /**
   * Kills the worm.
   */
  public void killWorm() {
    this.isAlive = false;
  }

  /**
   * Returns if the worm is alive or not.
   * @return True if the worm is alive, false case not.
   */
  public boolean isAlive() {
    return isAlive;
  }

  /**
   * Returns where the head is - the x coordinate.
   * @return The head's x coordinate.
   */
  public double get_X_head() {
    return head.get_X();
  }

  /**
   * Returns where the head is - the x coordinate.
   * @return The head's x coordinate.
   */
  public double get_Y_head() {
    return head.get_Y();
  }

  /**
   * Returns an array containg the worm drawing.
   * @return An array full of polygons.
   */
  public Polygon[] getDraw() {
    Polygon[] polygon = new Polygon[NUMBER_OF_PARTICLES + 1];
    polygon[0] = head.getPolygon();
    for (int k = 0; k < NUMBER_OF_PARTICLES; k++) {
      polygon[k+1] = body[k].getPolygon();
    }
    return polygon;
  }
}